const Joi = require("joi");
const AppleAuth = require("apple-auth");
const jwt = require("jsonwebtoken");
module.exports = class AppleAuthUtil {
  _getAppleAuth(ctx) {
    const {
      config: { iosAuth },
    } = ctx;
    const useBundleId = ctx.request.body.useBundleId;
    return new AppleAuth(
      {
        client_id: useBundleId === true ? iosAuth.bundleId : iosAuth.serviceId,
        team_id: iosAuth.teamId,
        redirect_uri: iosAuth.redirectUri,
        key_id: iosAuth.keyId,
      },
      iosAuth.authKey,
      "text"
    );
  }
  async auth(ctx) {
    await ctx.validateAsync({
      body: {
        code: Joi.string().required(),
      },
      status: 10001,
    });
    const body = ctx.request.body;
    const appleAuth = this._getAppleAuth(ctx);
    try {
      const res = await appleAuth.accessToken(body.code);
      const idToken = jwt.decode(res.id_token);
      const data = {
        type: 3,
        openid: idToken.sub,
      };
      if (idToken.email) {
        data.email = idToken.email;
      }
      if (idToken.user) {
        const { name } = JSON.parse(idToken.user);
        data.nickname = name;
      }
      ctx.respond(data);
    } catch (ex) {
      console.error(ex);
      ctx.throw("An error occurred!");
    }
  }

  async refresh(ctx) {
    const query = ctx.query;
    const appleAuth = this._getAppleAuth(ctx);
    try {
      const accessToken = await appleAuth.refreshToken(query.refreshToken);
      ctx.respond(accessToken);
    } catch (ex) {
      console.error(ex);
      ctx.throw("An error occurred!");
    }
  }

  async authCallback(ctx) {
    const {
      config: { iosAuth },
    } = ctx;
    const redirect = `intent://callback?${new URLSearchParams(
      ctx.request.body
    ).toString()}#Intent;package=${
      iosAuth.bundleId
    };scheme=signinwithapple;end`;
    console.log(`Redirecting to ${redirect}`, ctx.query);
    ctx.redirect(redirect, 307);
  }
};
